package com.jrx.anytxn.atom.service.impl;

import com.jrx.anytxn.atom.bean.CustBatchSaveBean;
import com.jrx.anytxn.atom.service.BaseBatchAccoutHandle;
import com.jrx.anytxn.common.exception.TxnBizException;
import com.jrx.anytxn.common.exception.TxnException;
import com.jrx.anytxn.customer.entity.CmCustomerFirstLevel;
import com.jrx.anytxn.param.entity.PrDelqTable;
import com.jrx.anytxn.param.entity.PrOrganizationTable;
import com.jrx.anytxn.param.service.product.IDelqTableService;
import com.jrx.anytxn.param.service.system.IOrganizationTableService;
import com.jrx.anytxn.transaction.bean.DealDelqBean;
import com.jrx.anytxn.transaction.bean.DelqSaveBean;
import com.jrx.anytxn.transaction.constant.TransBizConstant;
import com.jrx.anytxn.transaction.entity.*;
import com.jrx.anytxn.transaction.mapper.ext.ExtAmLoanMainInfoMapper;
import com.jrx.anytxn.transaction.service.IDealDelqService;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @program: anytxn-cf-parent
 * @description: 客户批量-延滞处理
 * @author: xiaoyu.jing
 * @date: 2020-09-01 09:35
 **/
@Order(20)
@Service
public class DelqHandle extends BaseBatchAccoutHandle<DelqSaveBean> {

    Logger logger = LoggerFactory.getLogger(DelqHandle.class);

    @Autowired
    private IOrganizationTableService organizationTableService;

    @Autowired
    private IDealDelqService delqService;

    @Autowired
    private IDelqTableService delqTableService;


    /**
     * 延滞业务逻辑处理
     *
     * @return
     * @throws TxnException
     */
    @Override
    public List<DelqSaveBean> handBatchAccout() throws TxnException {
        CustBatchSaveBean custBatchSaveBean = CustBatchHelper.getCustBatchLocal();
        List<AmRepaymentPlanInfo> dealPlanList = custBatchSaveBean.getDealPlanList();
        if (CollectionUtils.isEmpty(dealPlanList)) {
            return null;
        }


        List<DelqSaveBean> delqSaveBeanList = new ArrayList<>();
        CmCustomerFirstLevel firstLevel = custBatchSaveBean.getDealCust();
        String tenantId = firstLevel.getTenantId();
        PrOrganizationTable org = organizationTableService.findByOrId(TransBizConstant.DEFAULT_ORG_ID, tenantId);
        Date today = org.getToday();
        Date lastProcessDay = org.getLastProcessingDate();
        List<AmRepaymentPlanInfo> onDuePlanList = dealPlanList.stream()
                .filter(plan -> TransBizConstant.LOAN_PLAN_STATUS_1.equals(plan.getPlanStatus()))
                .filter(plan -> today.compareTo(plan.getPaymentDueDate()) >= 0)
                .filter(plan -> lastProcessDay.compareTo(plan.getPaymentDueDate()) <= 0)
                .collect(Collectors.toList());

        this.dealDelq(onDuePlanList, delqSaveBeanList, today);

        List<AmRepaymentPlanInfo> overDuePlanList = dealPlanList.stream()
                .filter(plan -> TransBizConstant.LOAN_PLAN_STATUS_2.equals(plan.getPlanStatus()))
                .collect(Collectors.toList());
        this.dealDelq(overDuePlanList, delqSaveBeanList, today);

        //更新订单逾期天数
        Map<String, List<DelqSaveBean>> delqSaveBeanMap = delqSaveBeanList.stream().filter(Objects::nonNull)
                .collect(Collectors.groupingBy(bean -> bean.getUpdatePlan().getLoanId()));

        if(null == delqSaveBeanMap){
            return null;
        }

        delqSaveBeanMap.forEach(
                (loanId,list) -> {
                    AmLoanAccountInfo orgiLoanAcct = custBatchSaveBean.getDealLoanAccountList().stream()
                            .filter(loan -> loanId.equals(loan.getLoanId())).findFirst().get();
                    AmLoanMainInfo orgiLoanMain = custBatchSaveBean.getDealLoanMainList().stream()
                            .filter(loan -> loanId.equals(loan.getLoanId())).findFirst().get();

                    PrDelqTable prDelqTable = null;
                    try {
                        prDelqTable = delqTableService.findByDelqId(tenantId, orgiLoanMain.getDelqTableId());
                    } catch (TxnBizException e) {
                        throw new RuntimeException(e);
                    }

                    if (TransBizConstant.YES_FLAG.equals(orgiLoanAcct.getChargeoffFlag()) && TransBizConstant.NO_FLAG.equals(prDelqTable.getChargeoffDelqFlag())) {
                        return;
                    }

                    DelqSaveBean delqSaveBean = list.stream().max(Comparator.comparingInt(bean -> bean.getUpdatePlan().getDelqDays())).get();
                    AmLoanAccountInfo updateLoan = delqSaveBean.getUpdateLoan();
                    if (null == updateLoan) {
                        updateLoan = new AmLoanAccountInfo();
                        updateLoan.setId(orgiLoanAcct.getId());
                        updateLoan.setCustomerId(orgiLoanAcct.getCustomerId());
                        updateLoan.setTenantId(orgiLoanAcct.getTenantId());
                    }
                    updateLoan.setDelqDays(delqSaveBean.getUpdatePlan().getDelqDays());
                    delqSaveBean.setUpdateLoan(updateLoan);
                }
        );
        logger.info("DelqHandle用户:{},需要处理的订单：{}",
                custBatchSaveBean.getDealCust().getCustomerId(),
                custBatchSaveBean.getDealLoanAccountList().stream().map(AmLoanAccountInfo::getLoanId).collect(Collectors.joining(","))
        );
        return delqSaveBeanList;
    }

    /**
     * 根据还款计划处理延滞
     *
     * @param delqPlanList
     * @param delqSaveBeanList
     * @param today
     * @throws TxnBizException
     */
    private void dealDelq(List<AmRepaymentPlanInfo> delqPlanList, List<DelqSaveBean> delqSaveBeanList, Date today) throws TxnBizException {
        if (CollectionUtils.isEmpty(delqPlanList)) {
            return;
        }

        CustBatchSaveBean custBatchSaveBean = CustBatchHelper.getCustBatchLocal();
        List<AmLoanMainInfo> dealLoanMainList = custBatchSaveBean.getDealLoanMainList();
        List<AmLoanAccountInfo> dealLoanAcctList = custBatchSaveBean.getDealLoanAccountList();
        List<AmAccountMainInfo> dealAcctList = custBatchSaveBean.getDealAcctList();
        List<AmDelinquencyInfo> dealDelqAcctList = custBatchSaveBean.getDealDelqAcctList();
        for (AmRepaymentPlanInfo delqPlan : delqPlanList) {
            String loanId = delqPlan.getLoanId();
            int billingTenor = delqPlan.getBillingTenor();

            AmLoanMainInfo loanMainInfo = dealLoanMainList.stream().filter(loanMain -> loanId.equals(loanMain.getLoanId())).findFirst().get();
            AmLoanAccountInfo loanAccountInfo = dealLoanAcctList.stream().filter(loanAcct -> loanId.equals(loanAcct.getLoanId())).findFirst().get();

            List<AmAccountMainInfo> acctList = dealAcctList.stream()
                    .filter(acct -> loanId.equals(acct.getLoanId()))
                    .filter(acct -> billingTenor == acct.getBillingTenor())
                    .filter(acct -> Arrays.asList(TransBizConstant.ACCOUNT_TYPE_04, TransBizConstant.ACCOUNT_TYPE_03
                            , TransBizConstant.ACCOUNT_TYPE_06).contains(acct.getAccountType()))
                    .filter(acct -> TransBizConstant.ACCOUNT_STATUS_1.equals(acct.getAccountStatus()))
                    .collect(Collectors.toList());
            AmDelinquencyInfo delqAcct = dealDelqAcctList.stream()
                    .filter(acct -> loanId.equals(acct.getLoanId()))
                    .filter(acct -> billingTenor == acct.getBillingTenor())
                    .findFirst().orElse(null);

            DealDelqBean bean = new DealDelqBean();
            bean.setBusinessDate(today);
            bean.setRepaymentPlanInfo(delqPlan);
            bean.setLoanMain(loanMainInfo);
            bean.setLoanAcct(loanAccountInfo);
            bean.setAcctList(acctList);
            bean.setDelqAcct(delqAcct);
            DelqSaveBean delqSaveBean = delqService.dealDelq(bean);
            delqSaveBeanList.add(delqSaveBean);
        }
    }
}
